
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>


#include <linux/netlink.h>
#include <libnetfilter_log/libnetfilter_log.h>

FILE *fp;
static int print_pkt(struct nflog_data *ldata)
{
	struct ip* iphdr;
	struct tcphdr* tcphdr;
	char *payload;
	int payload_len = nflog_get_payload(ldata, &payload);
    char srcip[30], dstip[30];

    iphdr = (struct ip*)payload;
    memset(srcip, 0, sizeof(srcip));
    memset(dstip, 0, sizeof(dstip));
    strcpy(srcip, inet_ntoa(iphdr->ip_src));
    strcpy(dstip, inet_ntoa(iphdr->ip_dst));
printf("ipinfo %s -> %s \n", srcip, dstip);
	// Advance to the transport layer header then parse and display
	// the fields based on the type of hearder: tcp, udp or icmp.
	payload += 4*iphdr->ip_hl;
	switch (iphdr->ip_p)
	{
	case IPPROTO_TCP:
	tcphdr = (struct tcphdr*)payload;
//	int srcport = ntohs(tcphdr->source);
	char strPort[15], targetInfo[128];
//	memset(strPort, 0, sizeof(strPort));
	memset(targetInfo, 0, sizeof(targetInfo));
//	sprintf(strPort, "%d", srcport);
	sprintf(targetInfo, "%d->%s:%d \n", ntohs(tcphdr->source),
			dstip, ntohs(tcphdr->dest));
	fwrite(targetInfo, 1, (strlen(targetInfo)+1), fp);
	fflush(fp);

	break;
	}
	return 0;
}

static int cb(struct nflog_g_handle *gh, struct nfgenmsg *nfmsg,
		struct nflog_data *nfa, void *data)
{
	print_pkt(nfa);
	return 0;
}


int main(int argc, char **argv)
{
	struct nflog_handle *h;
	struct nflog_g_handle *qh;
	int rv, fd;
	char buf[4096];
	fp = fopen("/sdcard/connTracker", "wb+");

	if(fp == NULL) {
		fprintf(stderr, "create file failed \n");
		exit(1);
	}

	h = nflog_open();
	if (!h) {
		fprintf(stderr, "error during nflog_open()\n");
		exit(1);
	}

	printf("unbinding existing nf_log handler for AF_INET (if any)\n");
	if (nflog_unbind_pf(h, AF_INET) < 0) {
		fprintf(stderr, "error nflog_unbind_pf()\n");
		exit(1);
	}

	printf("binding nfnetlink_log to AF_INET\n");
	if (nflog_bind_pf(h, AF_INET) < 0) {
		fprintf(stderr, "error during nflog_bind_pf()\n");
		exit(1);
	}
	printf("binding this socket to group 0\n");
	qh = nflog_bind_group(h, 0);
	if (!qh) {
		fprintf(stderr, "no handle for grup 0\n");
		exit(1);
	}

	printf("setting copy_packet mode\n");
	if (nflog_set_mode(qh, NFULNL_COPY_PACKET, 0xffff) < 0) {
		fprintf(stderr, "can't set packet copy mode\n");
		exit(1);
	}

	fd = nflog_fd(h);

	printf("registering callback for group 0\n");
	nflog_callback_register(qh, &cb, NULL);

	printf("going into main loop\n");
	while ((rv = recv(fd, buf, sizeof(buf), 0)) && rv >= 0) {
//		printf("pkt received (len=%u)\n", rv);

		/* handle messages in just-received packet */
		nflog_handle_packet(h, buf, rv);
	}
	printf("unbinding from group 0\n");
	nflog_unbind_group(qh);

#ifdef INSANE
	/* norally, applications SHOULD NOT issue this command,
	 * since it detaches other programs/sockets from AF_INET, too ! */
	printf("unbinding from AF_INET\n");
	nflog_unbind_pf(h, AF_INET);
#endif

	printf("closing handle\n");
	nflog_close(h);
	fclose(fp);
	return EXIT_SUCCESS;
}
